Skip to content

Rename @launchstack/search to @launchstack/retrieval and consolidate all retrieval algorithms and tools into it - #371

Merged
Deodat-Lawson merged 6 commits into
mainfrom
claude/predictive-doc-analysis-llm-ad776c
Sep 1, 2026
Merged

Rename @launchstack/search to @launchstack/retrieval and consolidate all retrieval algorithms and tools into it#371
Deodat-Lawson merged 6 commits into
mainfrom
claude/predictive-doc-analysis-llm-ad776c

Conversation

@Deodat-Lawson

@Deodat-Lawson Deodat-Lawson commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Renames packages/searchpackages/retrieval and finishes the long-stalled boundary inversion: every retrieval algorithm and retrieval-facing tool now lives in the one brick, organized as one documented folder per algorithmalgorithms/{bm25,vector,fusion,ensemble,rlm,graph,reranking} and tools/{citation-builder,grounded-retrieval,rag-search-tool,rlm-search}, each folder carrying a README (what it is, how it works, when it wins), an index.ts surface, and colocated tests.
  • Merges the parallel retrieval stack that lived inside predictive-document-analysis: the five ANN variants become named modules under algorithms/vector/strategies/ (documentQ&A stops importing from another feature's folder), its private hybrid search dissolves into bm25/fts.ts + fusion/ (RRF), and three independent embedding clients (predictive's, plus three notes-vertical OpenAIEmbeddings instantiations) collapse into @launchstack/llm's embedding service.
  • The RagPort contract and retrieval behavior are unchanged; the ensemble's env reads become configureEnsemble() injected from the app's new composition seam (apps/web/src/server/rag/ensemble.ts), and old subpaths (./retrievers, ./reranking, ./citation-builder) survive one release as aliases. @launchstack/search joins the lint ban on legacy names.

Design doc (LaunchStack template, with resolutions recorded): https://claude.ai/code/artifact/d4082c18-aa54-48d7-ada7-fe4448c8f204

Related

Implements the Retrieval Brick consolidation design. Deliberately does not touch the predictive-document-analysis kill-or-rebuild decision — only the shared algorithms trapped in its folder.

Checklist

  • pnpm check passes (lint + typecheck) — lint 0 errors, no new warnings
  • pnpm --filter @launchstack/web test passes — 2,273 passed (196 suites), incl. integration tests against a migrated pgvector 16
  • Changeset added (.changeset/retrieval-rename.md)
  • New env vars documented — none added; the ensemble now reads fewer env vars (injected config instead)
  • UI changes exercised in a browser — no UI changes (API/package refactor only)
  • Docs updated — REPOSITORY.md brick table + DAG, package README, per-algorithm READMEs

Testing

  • Workspace-wide typecheck and ESLint boundary rules (including the renamed per-package blocks; retrieval's allowlist gains indexing for exactly one edge — the Neo4j graph backend reusing indexing's graph client).
  • Full apps/web jest suite plus evidence/conversion/retrieval/tools/worker/orchestration/indexing package suites, run against a migrated pgvector/pgvector:pg16 database (CI's image).
  • New golden retrieval tests (apps/web/__tests__/server/retrieval-golden.test.ts, gated on DATABASE_URL): pinned ensemble ranking on a fixed corpus, the RRF cross-leg-agreement property, a liveness check on the vector leg exactly as the ensemble constructs it, and a non-empty canary for the worst failure mode (silent empty-context retrieval).
  • Publish path: pnpm -r build + scripts/ci/check-package-exports.mjs — all 154 exports load from built output.

Notes for reviewers

  • Move-don't-edit was the rule: weights, thresholds, RRF constants, and SQL moved verbatim. The two real seams are ~/server/db → the store client (same engine connection — the app's db is already a proxy over it) and env flags → configureEnsemble({ graphRetrieval, notesLegs }).
  • Notes retrieval stays app-side (injected ensemble leg) rather than promoting documentNoteEmbeddings into packages/store: the engine/product migration-ledger boundary (check-schema-boundary.mjs) makes promotion a migration-history move. Recorded as the Q2 resolution in the design doc; reversible later.
  • grounded-retrieval moved from packages/tools with a re-export kept, so its four internal consumers and the pipelines' "no direct RAG port calls" architecture test hold unchanged.
  • The rag-search tool became a factory taking an app-supplied AccessValidator (document access is product schema). It had no live consumers; behavior is preserved for future wiring.
  • Ensemble searches now log a per-leg breakdown so a silently dead leg (graph peer down, empty notes) is visible in logs.
  • The branch merges origin/main as of 4dc8b0da (Drive-linked files + PDF conversion bricks); conflicts were the CI publish filter, REPOSITORY.md's table, and the lockfile.
  • Deferred: deprecating @launchstack/search 0.1.0 on npm (design Q5) and the predictive-analysis product decision.

🤖 Generated with Claude Code


Note

Medium Risk
Large cross-cutting refactor of document Q&A and predictive matching retrieval paths; ranking behavior is guarded by new golden tests but any missed import or ensemble misconfiguration could still yield silent empty context.

Overview
Renames @launchstack/search to @launchstack/retrieval and folds scattered retrieval code into one brick: algorithms under src/algorithms/ (bm25, vector with ANN strategies, fusion, ensemble, rlm, graph, reranking) and agent-facing tools under src/tools/. The old package name is ESLint-banned; legacy subpaths (./retrievers, ./reranking, ./citation-builder) remain as one-release aliases.

Moves implementation out of apps/web: the former ~/lib/tools/rag stack is removed; Q&A and related routes import algorithms from @launchstack/retrieval and ensemble search only through ~/server/rag/ensemble.ts, which calls configureEnsemble() with deployment flags and an injected notes leg (notes schema stays app-side). Document access for RAG tools lives in ~/server/rag/access.ts. Predictive-analysis annOptimizer and hybridSearch are deleted in favor of @launchstack/retrieval/algorithms/vector and fusion (hybridSearchWithRRF now takes an injected embedder). Graph/RLM retrievers use @launchstack/store/client instead of the app DB proxy.

Behavioral / wiring tweaks: the ensemble no longer reads process.env inside the package; graph enablement and Neo4j backend selection are split (config flag vs isNeo4jConfigured()). Ensemble runs log per-leg candidate counts. Notes and predictive embedding paths route through @launchstack/llm instead of direct LangChain OpenAI clients. New DB golden tests pin ensemble ranking on a fixed corpus when DATABASE_URL is set.

CI, REPOSITORY.md, engine/tools/worker/web dependencies, and Jest module maps are updated to @launchstack/retrieval.

Reviewed by Cursor Bugbot for commit d0efbb2. Bugbot is set up for automated code reviews on this repo. Configure here.

Deodat-Lawson and others added 6 commits August 29, 2026 16:21
Mechanical rename only — directory, package name, the 13 TS import
sites, five workspace dependents, jest moduleNameMapper, next.config
transpilePackages, the CI publish filter, the e2e-ingest paths, and the
pending changeset. ESLint: the brick list, the per-package block, and
the tools allowlist now say retrieval, and @launchstack/search joins
the legacy-name ban so stale branches fail loudly instead of silently
resolving nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… documented folders

Every algorithm and tool is now a folder with its own README, index.ts
surface, and colocated tests: algorithms/{bm25,vector,ensemble,rlm,graph,
reranking} and tools/{citation-builder,rag-search-tool}. The RLM, graph,
and ensemble retrievers move in from apps/web/src/lib/tools/rag with two
seams cut on the way: ~/server/db becomes the store client (same engine
connection), and the ensemble's env reads become configureEnsemble(),
called from the app's new composition seam ~/server/rag/ensemble.ts.

Notes retrieval stays app-side (its tables are product schema the engine
store cannot own) and joins the ensemble as an injected leg — resolving
design question Q2 the low-risk way. The Neo4j graph backend keeps using
indexing's graph client; retrieval's lint allowlist gains that one edge
(Q4). The rag-search tool becomes a factory taking an app-supplied
AccessValidator, since document access lives in product schema too.

Both shim layers (lib/tools/rag, server/rag re-exports) are deleted; old
package subpaths (./retrievers, ./reranking, ./citation-builder) survive
one release as aliases. Ensemble searches now log a per-leg breakdown so
a silently dead leg shows in logs, not just a smaller total.

Verified: workspace typecheck, lint at baseline (0 errors / 62 warnings),
retrieval+tools+evidence+conversion+worker+orchestration+indexing suites,
and the full apps/web jest run (2242 passed) including the vector-retriever
and document-creation integration tests against a migrated pgvector 16.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o the package

annOptimizer's five ANN variants become named, documented modules under
algorithms/vector/strategies/ (exact scan, ivf, prefiltered, matryoshka,
adaptive hybrid), with ANNOptimizer surviving as the config-driven
dispatcher — documentQ&A's AIQuery/AIChat routes now import it from the
package instead of reaching into another feature's folder. The feature's
private hybridSearch dissolves along the design's lines: the ts_rank
full-text leg into algorithms/bm25/fts.ts, generic Reciprocal Rank Fusion
plus the composed page-level hybrid search into algorithms/fusion/, with
the query embedder injected rather than chosen by the algorithm.

Two of the three independent embedding clients are retired: predictive's
utils/embeddings and all three notes-vertical OpenAIEmbeddings
instantiations now generate through @launchstack/llm's embedding service
(same endpoints, models, and dimensions — the files keep only env-pair
resolution, caching, and error semantics). One embedding transport remains.

Verified: workspace typecheck, lint at baseline, retrieval + tools vitest,
full apps/web jest (2242 passed) against the migrated pgvector database.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
grounded-retrieval relocates from packages/tools — it is a retrieval
policy, not a vertical capability, and holding it in tools forced a
cross-brick import for every consumer. A re-export keeps the old path
alive for brand-voice/company-context/claim-evidence/persona and the
pipelines' architecture rule ("no feature calls the RAG port directly").

The cost-aware RLM search service moves out of documentQ&A wholesale:
its only app dependencies turned out to be compositions of llm-package
primitives (createEmbeddingModel + resolveEmbeddingIndex) and the store
client, so it lands in tools/rlm-search with zero injected seams. The
Q&A services barrel and AIQueryRLM route re-point to the package.

Every tool folder now carries the convention: README, index.ts surface,
implementation beside it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rface

Four golden tests against the migrated pgvector database pin the moved
ensemble's behavior: top-hit ranking on a fixed corpus, the RRF property
that cross-leg agreement beats a single leg's top rank, a liveness check
on the vector leg exactly as the ensemble constructs it, and the
silent-death canary (retrieval on a seeded corpus must never be empty —
the failure mode the design named worst). If a change legitimately
improves ranking, the goldens move in the same commit, with a reason.

Also: the package README now documents the folder-per-algorithm layout
and subpath map, the changeset describes the full consolidation, and the
publish path is verified — all 154 workspace exports load from built
output (check-package-exports).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eside the retrieval rename

Conflicts: the CI publish filter (kept retrieval, added
document-conversion-engine), REPOSITORY.md (kept main's aligned table with
the two new bricks, re-applied the retrieval row and the tools-allowlist
rename), and the lockfile (regenerated from the merged manifests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
launch-stack Error Error Aug 30, 2026 8:00pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
pdr-ai-v2 Ignored Ignored Aug 30, 2026 8:00pm

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d0efbb2. Configure here.

Comment thread scripts/ci/e2e-ingest.mjs
);
const { buildCitations } = await import(
"../../packages/search/src/citation-builder.ts"
"../../packages/retrieval/src/citation-builder.ts"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E2E ingest uses stale retrieval paths

Medium Severity

The ingest e2e script still targets packages/retrieval/src/retrievers/bm25-retriever.ts and packages/retrieval/src/citation-builder.ts. Those files now live under algorithms/bm25 and tools/citation-builder, so the script cannot load the moved modules.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0efbb2. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0efbb2d79

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,151 @@
{
"name": "@launchstack/retrieval",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update Docker contexts for the renamed package

Renaming the workspace here deletes packages/search/package.json, but the dependency stages in apps/web/Dockerfile:23, apps/web/Dockerfile.prebuilt:28, and apps/worker/Dockerfile:27 still copy that exact path. Every build using any of these three inspected Dockerfiles therefore stops at COPY before dependencies can be installed; update those manifest paths and destinations to packages/retrieval as part of the rename.

Useful? React with 👍 / 👎.

Comment on lines +147 to +149
"neo4j-driver": {
"optional": true
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid statically requiring the optional Neo4j peer

When a consumer omits the peer explicitly marked optional here, importing @launchstack/retrieval/algorithms/ensemble, @launchstack/retrieval/algorithms, or the compatibility retrievers export still evaluates ensemble.ts, which statically imports ../graph, whose neo4j.ts statically imports neo4j-driver. This throws a module-resolution error before the default graphRetrieval: false configuration can disable that backend, so the Neo4j module needs to be loaded lazily or the driver must be a required dependency.

Useful? React with 👍 / 👎.

@Deodat-Lawson
Deodat-Lawson merged commit bafb0fc into main Sep 1, 2026
11 of 16 checks passed
@Deodat-Lawson
Deodat-Lawson deleted the claude/predictive-doc-analysis-llm-ad776c branch September 1, 2026 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant